<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    
  </style>
</head>
<body>
  
</body>
<script>
  // 自定义事件系统
  var myEvent = {
    // 消息队列：记录自定义事件名和对应的事件处理函数
    message:{},
    // 添加自定义事件和事件处理函数：参数1事件类型，参数2事件处理函数
    add:function(type, cb){
      // 先判断消息队列中是否存在当前要添加的事件
      if(myEvent.message[type]){
        // 存在，在原有的事件处理函数中，新增一个
        myEvent.message[type].push(cb);
      }else{
        // 不存在，直接设置事件处理函数(数组形式)
        myEvent.message[type] = [cb];
      }
    },
    // 发布事件：触发指定事件的所有事件处理函数
    emit:function(type){
      // 判断消息队列中是否存在该事件，不存在，直接结束
      if( !myEvent.message[type] )return;
      // 用来记录要向事件处理函数中发送的数据
      var arr = [];
      // 因为当前函数的第一个参数用来做事件类型了，所以从第二个参数往后才是要发送的数据
      for(var i=1;i<arguments.length;i++){
        arr.push(arguments[i]);
      }
      // 根据传入的事件类型，找到所有的事件处理函数，遍历
      myEvent.message[type].forEach(function(val){
        // 执行每个函数，并入处理好的要发送的数据
        val(arr);
      })
    }
  }

  // 测试
  // 绑定
  // myEvent.add("abc", f1);
  // myEvent.add("abc", f2);
  // myEvent.add("zxc", f2);
  // myEvent.add("zxc", f4);
  // 触发
  // myEvent.emit("zxc", 1,2,3,4,5,6);
  // 测试时准备使用的事件处理函数
  // function f1(){ console.log(1) }
  // function f2(res){
  //   console.log(2, res)
  // }
  // function f3(){ console.log(3) }
  // function f4(res){
  //   console.log(4, res)
  // }

  // 观察事件消息队列
  // console.log(myEvent.message);



  // 系统功能1
  function fn1(){
    var data = "hello";
    // fn1将data发给了fn2
    myEvent.emit("abc", data);
  }

  // 系统功能2
  function fn2(){
    var msg = "world";
    // fn2接收fn1可能发过来的数据
    myEvent.add("abc", function(d){
      console.log(d);   // "hello"
    });
  }

  // 系统功能2：准备接收数据的一方
  fn2();

  // 系统功能1：发送数据的一方
  fn1();
  
  
</script>
</html>